import * as React from 'react';
import { Props, State } from '../type';
import { DatePicker } from '../../datepicker/view';
import moment from 'moment';
import { InputNumber } from '../../input-number/view';
import _ from 'lodash';
import { getDefaultHM, isMaxM, isMinM } from '../utils';
import { AppToast } from '@/utils/app-func';
import { WrapFormItem } from '@/plugins/form/form-components/common/form-item/formItem-decorate';
const DetailDate = WrapFormItem(DatePicker);
const DetailNumber = WrapFormItem(InputNumber);

export class RangePicker extends React.Component<Props, State> {
  public static defaultProps = new Props();
  public state = new State();

  constructor(props: Props) {
    super(props);
    this.startDateChange = this.startDateChange.bind(this);
    this.endDateChange = this.endDateChange.bind(this);
  }

  range(start: number, end: number) {
    const result: number[] = [];
    for (let i = start; i < end; i++) {
      result.push(i);
    }
    return result;
  }

  public isSameDate(start: moment.Moment, end: moment.Moment) {
    return start.format('YYYY-MM-DD') === end.format('YYYY-MM-DD');
  }
  public isSameDateHour(start: moment.Moment, end: moment.Moment) {
    if (!this.isSameDate(start, end)) return false;
    return start.hours() === end.hours();
  }

  startDateChange(startDate?: string) {
    const endDate = this.props.form?.getFieldValue(
      this.props.children[1].props.code,
    );
    console.log('startDateChange', startDate, endDate);
    // 校验日期大小
    if (
      this.props.children[0]?.props.mode === 'time' && // 只有天数是可以选择同一天的
      endDate &&
      startDate &&
      moment(endDate).valueOf() <= moment(startDate).valueOf()
    ) {
      console.log('===1===结束时间必须大于开始时间');
      AppToast({ type: 2, message: '结束时间必须大于开始时间' });
      const startMoment = getDefaultHM(moment(endDate), 'prev');
      startDate = startMoment.format('YYYY-MM-DD HH:mm');
      this.props.form?.setFieldsValue({
        [this.props.children[0].props.code]: startDate
      });
    }
    let diffDay;
    if (startDate && endDate) {
      diffDay = this.calcDurations(startDate, endDate);
    }
    if (this.props.isAutoCalc) {
      this.props.form?.setFieldsValue({
        [this.props?.children[2]?.props.code]: diffDay
      });
    }
  }

  endDateChange(endDate?: string) {
    const startDate = this.props.form?.getFieldValue(
      this.props?.children[0]?.props.code,
    );
    console.log('endDateChange', startDate, endDate, this.props);
    // 校验日期大小
    if (
      this.props.children[0]?.props.mode === 'time' && // 只有天数是可以选择同一天的
      endDate &&
      startDate &&
      moment(endDate).valueOf() <= moment(startDate).valueOf()
    ) {
      console.log('===2===结束时间必须大于开始时间');
      AppToast({ type: 2, message: '结束时间必须大于开始时间' });
      const endDateMoment = getDefaultHM(moment(startDate), 'next');
      endDate = endDateMoment.format('YYYY-MM-DD HH:mm');
      this.props.form?.setFieldsValue({
        [this.props.children[1].props.code]: endDate
      });
    }
    let diffDay;
    if (startDate && endDate) {
      diffDay = this.calcDurations(startDate, endDate);
    }
    if (this.props.isAutoCalc) {
      this.props.form?.setFieldsValue({
        [this.props?.children[2]?.props.code]: diffDay
      });
    }

  }

  calcDurations(startDate: string, endDate: string) {
    if (!this.props.isAutoCalc) return null;
    const diffTime =
      new Date(endDate.replace(/-/g, '/')).getTime() -
      new Date(startDate.replace(/-/g, '/')).getTime();

    let time;
    if (this.props.children[0].props.mode === 'time') {
      time = diffTime / (1000 * 60 * 60);
    } else {
      time = diffTime / (1000 * 60 * 60 * 24) + 1;
    }
    this.props.onRangeDateChange &&
      this.props.onRangeDateChange({ startDate, endDate, time });
    this.onChange(time);
    return time;
  }

  private onChange = (value: any) => {
    if (this.props.form) {
      const result = value ? value : undefined;
      console.log('change-child2');
      this.props.form.setFieldsValue({ [this.props.code]: result });
    }
    // this.props.onChange && this.props.onChange(value);
  };

  public getTimeOptions(type: 'start' | 'end') {
    // 如果模式为时间，进行限制
    const children = this.props.children || [];
    let timeOptions = {};
    if (children[0].props.mode !== 'time') {
      return timeOptions;
    }
    let compare: string | undefined;
    if (type === 'end') {
      compare = this.props.form?.getFieldValue(children[0]?.props.code);
    } else {
      compare = this.props.form?.getFieldValue(children[1]?.props.code);
    }
    const compareMoment = compare ? moment(compare) : undefined;
    // 计算默认值
    timeOptions = {
      disabledTime: (date: moment.Moment) => {
        return {
          disabledHours: () => {
            // 选择了同一天的时候 如果是结束选框，时间不能比开始的小；如果是开始，不能比结束大
            if (type === 'end') {
              if (!compareMoment) return null;
              // 同一天才需要比较
              if (date && !this.isSameDate(compareMoment, date)) return null;
              const startH = compareMoment.get('hour');
              // 结束时间是否能跟开始时间选同一小时 取决于开始时间的分钟是不是选择了最大
              if (isMaxM(compareMoment)) {
                return _.range(0, startH + 1); // 不能选择与开始时间相同的小时
              }
              return _.range(0, startH);
            }
            // 开始时间限制
            if (type === 'start') {
              if (!compareMoment) return null;
              // 同一天才需要比较
              if (date && !this.isSameDate(moment(compareMoment), date))
                return null;
              const endH = moment(compareMoment).get('hour');
              // 开始时间是否能跟结束时间选择同一小时 取决于结束时间的分钟是不是选择了最小
              if (isMinM(compareMoment)) {
                return _.range(endH, 24); // 不能选择结束时间同一小时
              }
              return _.range(endH + 1, 24);
            }
            return [];
          },
          disabledMinutes: () => {
            // if (!compareMoment) return null;
            // // 同一时
            // if (date && !this.isSameDateHour(compareMoment, date)){
            //   return null;
            // };

            return [..._.range(1, 30), ..._.range(31, 60)];
          }
        };
      },
      showTime: {
        hideDisabledOptions: true,
        minuteStep: 30,
        defaultValue: getDefaultHM(
          compareMoment,
          type === 'start' ? 'prev' : 'next'
        ),
        format: 'HH:mm'
      }
    };
    return timeOptions;
  }

  public isTime = () => {
    return this.props.children[0].props.mode === 'time';
  };

  GetDetail = () => {
    const children = this.props.children || [];
    if (!children) return null;

    const {
      disabled,
      readonly,
      permission,
      formValues,
      visibleConditions
    } = this.props;

    const startTimeOptions = this.getTimeOptions('start');
    const endTimeOptions = this.getTimeOptions('end');
    const startTime = this.props.form?.getFieldValue(this.props?.children[0]?.props.code);
    const endTime = this.props.form?.getFieldValue(this.props?.children[1]?.props.code);
    return (
      <>
        <DetailDate
          {...children[0]?.props}
          maxDate={endTime}
          {...startTimeOptions}
          visibleConditions={visibleConditions}
          formValues={formValues}
          disabled={disabled}
          readonly={readonly}
          permission={permission}
          onChange={this.startDateChange}
          showNow={false}
        />
        <DetailDate
          {...children[1]?.props}
          minDate={startTime}
          {...endTimeOptions}
          visibleConditions={visibleConditions}
          formValues={formValues}
          disabled={disabled}
          readonly={readonly}
          permission={permission}
          onChange={this.endDateChange}
          showNow={false}
        />
        {this.props.isAutoCalc ? (
          <DetailNumber
            {...children[2]?.props}
            disabled
            visibleConditions={visibleConditions}
            formValues={formValues}
            readonly={readonly}
            permission={permission}
            onChange={this.onChange}
          />
        ) : null}
      </>
    );
  }
  public render() {
    const children = this.props.children || [];
    if (!children) return null;
    return (
      <>
        {
          this.GetDetail()
        }
      </>
    );
  }
}
